package com.zoe.onelink.core.web.resolver;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zoe.onelink.annotation.web.arg.RequestArg;
import com.zoe.onelink.common.enumeration.ExceptionCodeEnum;
import com.zoe.onelink.common.exception.ApiException;
import com.zoe.onelink.core.property.OnelinkProperties;
import org.springframework.core.MethodParameter;

/**
 * <p>标题: 分页入参处理器</p>
 * <p>描述: </p>
 * <p>版权: Copyright (c) 2021</p>
 * <p>公司: 智业软件股份有限公司</p>
 *
 * @version: 1.0
 * @author: ruansheng
 * @date: 2021-11-04
 */
public class PageMethodArgumentResolver extends AbstractObjectMapperMethodArgumentResolver {

    public PageMethodArgumentResolver(ObjectMapper objectMapper, OnelinkProperties.Web.Arg requestArgProp) {
        super(objectMapper, requestArgProp);
    }


    @Override
    protected boolean couldResolveArgument(MethodParameter parameter) {
        return IPage.class.isAssignableFrom(parameter.getParameterType())
                || PAGE_NODE_NAME.equals(parameter.getParameterName())
                || PAGE_SIZE_NODE_NAME.equals(parameter.getParameterName());
    }

    @Override
    protected Object resolveArgument(JsonNode rootNode, JavaType paramType, RequestArg requestArg, String paramName, int paramIndex) throws Exception {
        Object retVal;
        JsonNode pageNode = rootNode.path(paramName);
        if (IPage.class.isAssignableFrom(paramType.getRawClass())) {
            if (pageNode.isMissingNode() || !pageNode.isObject()) {
                long currPage = rootNode.path(PAGE_NODE_NAME).asLong(1L);
                long pageSize = rootNode.path(PAGE_SIZE_NODE_NAME).asLong(10L);
                retVal = paramType.getRawClass().getConstructor(long.class, long.class).newInstance(currPage, pageSize);
            } else {
                retVal = this.om.readValue(pageNode.toString(), paramType);
            }
        } else if (PAGE_NODE_NAME.equals(paramName)) {
            if (pageNode.isMissingNode()) {
                retVal = 1L;
            } else if (pageNode.isObject()) {
                retVal = pageNode.get(PAGE_NODE_NAME).asLong(1L);
            } else {
                retVal = pageNode.asLong(1L);
            }
        } else if (PAGE_SIZE_NODE_NAME.equals(paramName)) {
            if (pageNode.isMissingNode()) {
                JsonNode pageNodeObj = rootNode.path(PAGE_NODE_NAME);
                retVal = pageNodeObj.isMissingNode() ? 10L : pageNodeObj.get(PAGE_SIZE_NODE_NAME).asLong(10L);
            } else {
                retVal = pageNode.asLong(10L);
            }
        } else {
            throw ApiException.createEx(ExceptionCodeEnum.REQ_ARG_JSON_PARSE_EXCEPTION, paramIndex, paramName);
        }
        return retVal;
    }
}
